﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using RSAEncryptionLib;
using DataAccessObject;
using DataTransferObjects;

namespace Business
{
    public class DigitalSignatureBUS
    {
        static public int GetSignature(int iUserID, string fileInput, string fileOuput)
        {
            int iNormal = 0;
            KeyInforDTO keyInfor = KeyDAO.getKeyInforFromDB(iUserID);
            HashAlgorithm hash = new MD5CryptoServiceProvider();
            FileStream fsIn = new FileStream(fileInput, FileMode.Open, FileAccess.Read);
            FileStream fsOut = new FileStream(fileOuput, FileMode.OpenOrCreate, FileAccess.Write);

            try
            {
                byte[] dataInput = new byte[fsIn.Length];
                fsIn.Read(dataInput, 0, dataInput.Length);

                byte[] resultHash = hash.ComputeHash(dataInput);

                RSAEncryption myRsa = new RSAEncryption();
                myRsa.importPrivateKey(keyInfor.rsaExponent, keyInfor.rsaModulus, keyInfor.rsaD);
                byte[] resultSignature = myRsa.PrivateEncryption(resultHash);

                fsOut.Write(resultSignature, 0, resultSignature.Length);
            }catch
            {
                iNormal = 1;
            }

            fsIn.Close();
            fsOut.Close();

            return iNormal;
        }

        static public int VerifySignature(string fileInput, string fileSignatureInput)
        {

            bool bIsEqual = true;
            int i = 0;
            HashAlgorithm hash = new MD5CryptoServiceProvider();
            FileStream fsIn = new FileStream(fileInput, FileMode.Open, FileAccess.Read);
            FileStream fsInCheck = new FileStream(fileSignatureInput, FileMode.Open, FileAccess.Read);
            

            try
            {
                byte[] dataInput = new byte[fsIn.Length];
                fsIn.Read(dataInput, 0, dataInput.Length);
                byte[] resultHash = hash.ComputeHash(dataInput);


                byte[] signatureInput = new byte[fsInCheck.Length];
                fsInCheck.Read(signatureInput, 0, signatureInput.Length);

                KeyInforDTO[] keysInfor = KeyDAO.getKeysInforFromDB();

                foreach (KeyInforDTO keyInfor in keysInfor)
                {
                    RSAEncryption myRsa = new RSAEncryption();
                    myRsa.importPublicKey(keysInfor[i].rsaExponent, keysInfor[i].rsaModulus);
                    byte[] hashOriginal = myRsa.PublicDecryption(signatureInput);

                    if (resultHash.Length != hashOriginal.Length)
                    {
                        bIsEqual = false;
                    }
                    else
                    {
                        for (int offset = 0; offset < resultHash.Length; ++offset)
                        {
                            if (!resultHash[offset].Equals(hashOriginal[offset]))
                            {
                                bIsEqual = false;
                                break;
                            }
                        }
                    }

                    if (bIsEqual)
                    {
                        return keysInfor[i].iUserID;
                    }
                    ++i;
                }
                    
                fsIn.Close();
                fsInCheck.Close();
            }
            catch (Exception ex)
            {                
                return -1;
            }

            return -1;
        }
    }
}
